package cn.tml.innermost.user.service.impl;

import cn.tml.innermost.framework.entity.enums.ResultCode;
import cn.tml.innermost.framework.entity.vo.ResultMessage;
import cn.tml.innermost.framework.exception.ServiceException;
import cn.tml.innermost.framework.security.AuthUser;
import cn.tml.innermost.framework.security.context.UserContext;
import cn.tml.innermost.music.vo.MusicListInfoVO;
import cn.tml.innermost.user.dos.CollectionMusicList;
import cn.tml.innermost.user.dos.MusicListRecord;
import cn.tml.innermost.user.dos.UserMusicList;
import cn.tml.innermost.music.params.MusicListParams;
import cn.tml.innermost.user.mapper.MusicListRecordMapper;
import cn.tml.innermost.user.vos.params.PageParams;
import cn.tml.innermost.user.vos.vo.MusicListRecordVO;
import cn.tml.innermost.user.vos.vo.MusicListVO;
import cn.tml.innermost.user.feign.UserToMusicFeignService;
import cn.tml.innermost.user.mapper.UserCollectionMusicListMapper;
import cn.tml.innermost.user.mapper.UserMusicListMapper;
import cn.tml.innermost.user.service.UserMusicListService;
import cn.tml.innermost.user.utils.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author welsir
 * @version 1.0
 * @description: TODO
 * @date 2022/10/20 23:05
 */
@CacheConfig
@Service
@Slf4j
public class UserMusicListServiceImpl implements UserMusicListService {
    @Resource
    private UserMusicListMapper userMusicListMapper;

    @Resource
    private MusicListRecordMapper musicListRecordMapper;
    @Resource
    private UserCollectionMusicListMapper userCollectionMusicListMapper;
    @Resource
    private UserInfoUtil userInfoUtil;
    @Resource
    UserToMusicFeignService userToMusicFeignService;

    /**
     * @description: 用户注册创建歌单
     * @param: [MusicListName, userName, userId]
     * @return: [MusicListName, userName, userId]
     * @author: WELSIR
     * @date: 2022/11/10 19:36
     */
    @Override
    public MusicListVO getRegisterMusicList(String MusicListName, String userName, Long userId) {
        return userInsertMusicList(MusicListName);
    }

    /**
     * @description: 用户手动新建歌单
     * @param: []
     * @return: []
     * @author: WELSIR
     * @date: 2022/10/21 0:06
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public MusicListVO insertMusicList(String musicListName) {
        UserMusicList userMusicList = userMusicListMapper.selectOne(new QueryWrapper<UserMusicList>().eq("title", musicListName).eq("user_id",userInfoUtil.getUserInfo().getId()));
        if (null != userMusicList) {
            throw new ServiceException(ResultCode.TITLE_EXIST);
        } else {
            return userInsertMusicList(musicListName);
        }
    }

    /**
     * @description: 新建歌单方法抽取
     * @param: [params]
     * @return: [params]
     * @author: WELSIR
     * @date: 2022/11/9 17:02
     */
    @Transactional(rollbackFor = Exception.class)
    public MusicListVO userInsertMusicList(String musicListName) {
        AuthUser currentUser = UserContext.getCurrentUser();
        String username = currentUser.getUsername();
        Long userId = currentUser.getId();

        MusicListParams musicListParams = new MusicListParams(musicListName,IdWorker.getId(),username,null,null);
        System.out.println(musicListParams);
        ResultMessage<MusicListInfoVO> res  = userToMusicFeignService.addMusicList(musicListParams);
        MusicListInfoVO musicListInfoVO =  res.getResult();
        System.out.println(musicListInfoVO);
        UserMusicList userMusicList = UserMusicList.builder()
                .userId(userId)
                .musicListId(musicListInfoVO.getId())
                .name(musicListName)
                .musicCount(musicListInfoVO.getMusicNums())
                .coverUrl(musicListInfoVO.getCoverUrl())
                .playsNums(musicListInfoVO.getPlaysNums())
                .authorName(username)
                .collectionNums(musicListInfoVO.getCollectionNums())
                .deleteFlag(false).build();
        if (userMusicListMapper.insert(userMusicList) != 1) {
            throw new ServiceException(ResultCode.INSERT_PLAY_LIST_FAIL);
        }
        return MusicListVO.valueOf(userMusicList);
    }

    /**
     * @description: 用户添加收藏歌单
     * @param: [MusicListId, loginName]
     * @return: [MusicListId, loginName]
     * @author: WELSIR
     * @date: 2022/10/22 17:32
     */
    @Override
    public Boolean insertCollectionMusicList(Long MusicListId) {
        Long userId = UserContext.getCurrentUser().getId();
        CollectionMusicList id = userCollectionMusicListMapper.selectOne(new QueryWrapper<CollectionMusicList>().eq("music_list_id", MusicListId).eq("user_id",userId));
        if(id!=null){
            return false;
        }
        ResultMessage<MusicListInfoVO> MusicListInfo = userToMusicFeignService.getMusicListInfo(MusicListId);
        MusicListInfoVO res = MusicListInfo.getResult();
        CollectionMusicList collectionMusicList = new CollectionMusicList(userId,MusicListId,res.getMusicNums(),res.getName(),res.getAuthorName(),res.getCoverUrl());
        if (userCollectionMusicListMapper.insert(collectionMusicList) != 1) {
            throw new ServiceException(ResultCode.INSERT_PLAY_LIST_FAIL);
        }
        return true;
    }

    /**
     * @description: 新增歌曲到歌单
     * @param: [id]
     * @return: [id]
     * @author: WELSIR
     * @date: 2022/10/21 0:38
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertSongToMusicList(Long musicId, Long musicListId) {
        ResultMessage<MusicListInfoVO> res = userToMusicFeignService.addMusicToMusicList(musicId, musicListId);
        MusicListInfoVO result = res.getResult();
        UpdateWrapper<UserMusicList> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("music_list_id",result.getId()).set("music_count",result.getMusicNums()).set("cover_url",result.getCoverUrl());
        userMusicListMapper.update(null, updateWrapper);
        return true;
    }

    /**
     * @description: 用户删除歌单（可以加入消息队列）
     * @param: [MusicListId, loginName]
     * @return: [MusicListId, loginName]
     * @author: WELSIR
     * @date: 2022/10/21 17:47
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteMusicList(Long musicListId) {
        /**
         * 首先判断是否为自建歌单，如果是则通知音乐模块删除
         */
        Long userId = UserContext.getCurrentUser().getId();
        QueryWrapper<UserMusicList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId).eq("music_list_id",musicListId);
        UserMusicList userMusicList = userMusicListMapper.selectOne(queryWrapper);
        if(userMusicList!=null){
            userMusicListMapper.delete(queryWrapper);
            userToMusicFeignService.delMusicList(musicListId);
            return true;
        }else {
            QueryWrapper<CollectionMusicList> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("user_id",userId).eq("music_list_id",musicListId);
            userCollectionMusicListMapper.delete(queryWrapper2);
        }
        return true;
    }

    /**
     * @description: 获取用户自建歌单信息
     * @param: [MusicListId]
     * @return: [MusicListId]
     * @author: WELSIR
     * @date: 2022/10/22 17:22
     */
    @Override
    public List<UserMusicList> getUserMusicList(Long userId) {
        //        获取用户信息
        List<UserMusicList> userMusicLists = userMusicListMapper.selectList(new QueryWrapper<UserMusicList>().eq("user_id", userId).eq("delete_flag",0).orderByDesc("create_time"));
        return userMusicLists;
    }

    /**
     * @description: 获取收藏歌单列表
     * @param: []
     * @return: []
     * @author: WELSIR
     * @date: 2022/10/23 20:43
     */
    @Override
    public List<CollectionMusicList> getUserCollectionMusicList(Long userId) {
        return userCollectionMusicListMapper.selectList(new QueryWrapper<CollectionMusicList>()
                .eq("user_id", userId));
    }

    /**
     * @description: 获取指定歌单冗余信息
     * @param: [MusicListId]
     * @return: [MusicListId]
     * @author: WELSIR
     * @date: 2022/10/23 20:44
     */
    @Override
    public MusicListVO getOneMusicList(Long musicListId) {
        ResultMessage<MusicListInfoVO> res = userToMusicFeignService.getMusicListInfo(musicListId);
        MusicListInfoVO MusicListInfoVO = res.getResult();
        MusicListVO MusicListVO = new MusicListVO();
        BeanCopyUtil.copyProperties(MusicListInfoVO,MusicListVO);
        return MusicListVO;
    }

    @Override
    public Boolean updateMusicList(MusicListParams musicListParams) {
        Long ListId = musicListParams.getMusicListId();
        QueryWrapper<UserMusicList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("music_list_id",ListId);
        UserMusicList userMusicList = userMusicListMapper.selectOne(queryWrapper);
        userMusicList.setName(musicListParams.getName());
        System.out.println(userMusicList);
        userMusicListMapper.update(userMusicList,queryWrapper);
        userToMusicFeignService.updateMusicList(musicListParams);
        return true;
    }

    /**
     * 修改歌单封面
     *
     * @param file
     * @return url
     */

    @Override
    public MusicListVO updateMusicListCover(Long id,MultipartFile file) {
        UserMusicList userMusicList = userMusicListMapper.selectById(id);
        String url = null;
        if(userMusicList == null)
            throw new ServiceException(ResultCode.MusicList_GET_FAIL);
        try{
            InputStream inputStream = file.getInputStream();
            String prefix = "MusicListCover";
            url = OssUtil.SaveToOss(inputStream,String.valueOf(id),prefix);
            MusicListParams MusicListParams = new MusicListParams();
            MusicListParams.setCoverUrl(url);
            MusicListParams.setMusicListId(id);
            this.updateMusicList(MusicListParams);
        }catch(Exception e){
            e.printStackTrace();
        }
        return MusicListVO.valueOf(userMusicList);
    }

    @Override
    public boolean insertMusicListRecord(MusicListRecord musicListRecord) {
        QueryWrapper<MusicListRecord> queryWrapper = new QueryWrapper<>();
        AuthUser authUser = UserContext.getCurrentUser();
        Long userId = authUser.getId();
        Long musicListId = musicListRecord.getMusicListId();
        queryWrapper.eq("user_id", userId).eq("music_list_id", musicListId);
        MusicListRecord savedRecord = musicListRecordMapper.selectOne(queryWrapper);
        if (savedRecord != null) {
            musicListRecordMapper.updateById(savedRecord);
        } else {
            musicListRecord.setUserId(userId);
            musicListRecordMapper.insert(musicListRecord);
        }
        return true;
    }

    @Override
    public List<MusicListRecordVO> selectMusicListRecord(PageParams pageParams) {
        List<MusicListRecordVO> res = new ArrayList<>();
        Integer startPage = pageParams.getStartPage();
        Integer onePageAmount = pageParams.getOnePageAmount();
        Long userId = UserContext.getCurrentUser().getId();
        QueryWrapper<MusicListRecord> queryWrapper = new QueryWrapper<>();
        Page<MusicListRecord> page = new Page<>(startPage,onePageAmount);
        queryWrapper.eq("user_id",userId).orderByDesc("create_time");
        Page<MusicListRecord> musicListRecordPage = musicListRecordMapper.selectPage(page, queryWrapper);
        List<MusicListRecord> records = musicListRecordPage.getRecords();
        for (MusicListRecord record : records) {
            res.add(MusicListRecordVO.valueOf(record));
        }
        return res;
    }
}
